package com.scriptlib;

import android.graphics.Bitmap;
import android.graphics.Point;

import java.util.List;

public class AnchorGraphicHelper {
    private static final int _NONE = -1;
    private static final int _LEFT = 0;
    private static final int _CENTER = 1;
    private static final int _RIGHT = 2;

    private final GraphicHelper BaseGraphicHelper;
    private final double Multiple;
    private final int Left, Top, Right, Bottom, Center, DevWidth, DevHeight;

    private  final  AJFunc AjFunc;

    /**
     * 静态构造函数
     *
     * @param obj:       aj_runtime
     * @param devWidth:  开发分辨率_宽
     * @param devHeight: 开发分辨率_高
     * @param left:      运行设备布局 startX
     * @param top:       运行设备布局 startY
     * @param right      运行设备布局 endX
     * @param bottom:    运行设备布局 endY
     */
    public static AnchorGraphicHelper Create(Object obj, int devWidth, int devHeight, int left, int top, int right, int bottom) {
        AnchorGraphicHelper helper = new AnchorGraphicHelper(obj, devWidth, devHeight, left, top, right, bottom);
        if (helper.BaseGraphicHelper != null) {
            return helper;
        }
        return null;
    }

    /**
     * 构造函数
     *
     * @param obj:         aj_runtime
     * @param description: 开发及运行参数
     */
    public static AnchorGraphicHelper Create(Object obj, int[] description) {
        AnchorGraphicHelper helper = new AnchorGraphicHelper(obj, description[0], description[1], description[2], description[3], description[4], description[5]);
        if (helper.BaseGraphicHelper == null) {
            return null;
        }
        return helper;
    }

    private AnchorGraphicHelper(Object obj, int devWidth, int devHeight, int left, int top, int right, int bottom) {
        this.BaseGraphicHelper = GraphicHelper.Create(obj);
        this.DevWidth = devWidth;
        this.DevHeight = devHeight;
        this.Left = left;
        this.Top = top;
        this.Right = right;
        this.Bottom = bottom;
        this.Center = Round((this.Right - this.Left + 1.0) / 2) + Left - 1;
        this.Multiple = (this.Bottom - this.Top + 1.0) / DevHeight;
        this.AjFunc = new AJFunc(obj);
    }

    static public String Version() {
        return AJFunc.Version();
    }

    static public String GetInfo() {
        return AJFunc.GetInfo();
    }

    public boolean ReInitialize() {
        return BaseGraphicHelper.ReInitialize();
    }

    public boolean KeepScreen(boolean sign) {
        return BaseGraphicHelper.KeepScreen(sign);
    }

    public boolean KeepScreen(Bitmap bitmap, boolean sign) {
        return BaseGraphicHelper.KeepScreen(bitmap, sign);
    }

    public void GetRedList() {
        BaseGraphicHelper.GetRedList();
    }

    public byte[] GetScreenData() {
        return BaseGraphicHelper.GetScreenData();
    }

    /**
     * 四舍六入五成双
     */
    public int Round(double num) {
        int local = (int) ((num - (int) num) * 100);
        if (local / 10 >= 6)
            return (int) num + 1;
        if (local / 10 <= 4)
            return (int) num;
        if (local % 10 == 0) {
            if ((int) num % 2 == 0) {
                return (int) num;
            }
        }
        return (int) num + 1;
    }

    /**
     * 获取与运行设备相关的范围
     *
     * @param sx:    开发分辨率的startX
     * @param sy:    开发分辨率的startY
     * @param smode: sx和sy的坐标对齐方式
     * @param ex:    开发分辨率的endX
     * @param ey:    开发分辨率的endY
     * @param emode: ex和ey的坐标对齐方式
     */
    public int[] GetRange(int sx, int sy, int smode, int ex, int ey, int emode) {
        int[] result = new int[4];
        Point startPoint = GetPoint(sx, sy, smode);
        Point endPoint = GetPoint(ex, ey, emode);
        result[0] = startPoint.x;
        result[1] = startPoint.y;
        result[2] = endPoint.x;
        result[3] = endPoint.y;
        return result;
    }

    /**
     * 获取与运行设备相关的范围
     *
     * @param sx:   开发分辨率的startX
     * @param sy:   开发分辨率的startY
     * @param ex:   开发分辨率的endX
     * @param ey:   开发分辨率的endY
     * @param mode: 坐标对齐方式
     */
    public int[] GetRange(int sx, int sy, int ex, int ey, int mode) {
        return GetRange(sx, sy, mode, ex, ey, mode);
    }

    /**
     * 获取与运行设备相关的坐标
     *
     * @param x:    开发分辨率的x
     * @param y:    开发分辨率的y
     * @param mode: 坐标对齐方式
     */
    public Point GetPoint(int x, int y, int mode) {
        Point result = new Point();
        if (mode == _LEFT || mode == _NONE) {
            result.x = Round(x * Multiple) + Left;
        } else if (mode == _CENTER) {
            result.x = Round(Center - (DevWidth / 2.0 - x - 1) * Multiple);
        } else if (mode == _RIGHT) {
            result.x = Round(Right - (DevWidth - x - 1) * Multiple);
        }
        result.y = Round(y * Multiple) + Top;
        return result;
    }

    public Bitmap GetBitmap() {
        return BaseGraphicHelper.GetBitmap();
    }

    public Bitmap GetBitmap(int sx, int sy, int ex, int ey) {
        return BaseGraphicHelper.GetBitmap(sx, sy, ex, ey);
    }

    public int[] GetPixel(int x, int y, int mode) {
        Point point = GetPoint(x, y, mode);
        return BaseGraphicHelper.GetPixel(point.x, point.y);
    }

    public String GetPixelStr(int x, int y, int mode) {
        Point point = GetPoint(x, y, mode);
        return BaseGraphicHelper.GetPixelStr(point.x, point.y);
    }

    public int GetPixelHex(int x, int y, int mode) {
        Point point = GetPoint(x, y, mode);
        return BaseGraphicHelper.GetPixelHex(point.x, point.y);
    }

    public int[][] GetCmpColorArray(int devWidth, int devHeight, int[][] description) {
        double multiple = (Bottom - Top + 1.0) / devHeight;
        int[][] result = new int[description.length][9];
        for (int i = 0; i < description.length; i++) {
            if (description[i][0] == _LEFT || description[i][0] == _NONE) {
                result[i][0] = Round(description[i][1] * multiple) + Left;
            } else if (description[i][0] == _CENTER) {
                result[i][0] = Round(Center - (devWidth / 2.0 - description[i][1] - 1) * multiple);
            } else if (description[i][0] == _RIGHT) {
                result[i][0] = Round(Right - (devWidth - description[i][1] - 1) * multiple);
            }
            result[i][1] = Round(description[i][2] * multiple) + Top;
            result[i][2] = (description[i][3] & 0xff0000) >> 16;
            result[i][3] = (description[i][3] & 0xff00) >> 8;
            result[i][4] = description[i][3] & 0xff;
            result[i][5] = result[i][6] = result[i][7] = result[i][8] = 0;

            if (description[i].length >= 5) {
                if (description[i].length == 6) {
                    result[i][8] = description[i][5];
                } else if (description[i][4] == 1) {
                    result[i][8] = description[i][4];
                } else {
                    result[i][5] = (description[i][4] & 0xff0000) >> 16;
                    result[i][6] = (description[i][4] & 0xff00) >> 8;
                    result[i][7] = description[i][4] & 0xff;
                }
            }
        }
        return result;
    }

    public int[][] GetCmpColorArray(String description) {
        String[] desc = description.split(",");
        int devWidth = Integer.parseInt(desc[0].trim());
        int devHeight = Integer.parseInt(desc[1].trim());
        double multiple = (Bottom - Top + 1.0) / devHeight;

        int[][] result = new int[desc.length - 2][9];
        for (int i = 2, j = 0; i < desc.length; i++, j++) {
            String[] currentDesc = desc[i].trim().split("\\|");
            switch (currentDesc[0]) {
                case "left":
                case "none":
                    result[j][0] = Round(Integer.parseInt(currentDesc[1]) * multiple) + this.Left;
                    break;
                case "center":
                    result[j][0] = Round(this.Center - (devWidth / 2.0 - Integer.parseInt(currentDesc[1]) - 1) * multiple);
                    break;
                case "right":
                    result[j][0] = Round(this.Right - (devWidth - Integer.parseInt(currentDesc[1]) - 1) * multiple);
                    break;
            }
            result[j][1] = Round(Integer.parseInt(currentDesc[2]) * multiple) + this.Top;
            int color = Integer.parseInt(currentDesc[3].replace("0x", ""), 16);
            result[j][2] = (color & 0xff0000) >> 16;
            result[j][3] = (color & 0xff00) >> 8;
            result[j][4] = color & 0xff;
            result[j][5] = result[j][6] = result[j][7] = result[j][8] = 0;
            if (currentDesc.length >= 5) {
                if (currentDesc[4].startsWith("0x")) {
                    int offsetColor = Integer.parseInt(currentDesc[4].replace("0x", ""), 16);
                    result[j][5] = (offsetColor & 0xff0000) >> 16;
                    result[j][6] = (offsetColor & 0xff00) >> 8;
                    result[j][7] = offsetColor & 0xff;
                } else {
                    result[j][8] = Integer.parseInt(currentDesc[4]);
                }

                if (currentDesc.length == 6) {
                    result[j][8] = Integer.parseInt(currentDesc[5]);
                }
            }
        }
        return result;
    }

    public int[][] GetFindColorArray(int devWidth, int devHeight, int[][] description) {
        int[][] result = new int[description.length][9];
        double multiple = (Bottom - Top + 1.0) / devHeight;
        if (description[0][0] == _LEFT || description[0][0] == _NONE) {
            result[0][0] = Round(description[0][1] * multiple) + Left;
        } else if (description[0][0] == _CENTER) {
            result[0][0] = Round(Center - (devWidth / 2.0 - description[0][1] - 1) * multiple);
        } else if (description[0][0] == _RIGHT) {
            result[0][0] = Round(Right - (devWidth - description[0][1] - 1) * multiple);
        }
        result[0][1] = Round(description[0][2] * multiple);
        result[0][2] = (description[0][3] & 0xff0000) >> 16;
        result[0][3] = (description[0][3] & 0xff00) >> 8;
        result[0][4] = description[0][3] & 0xff;
        result[0][5] = result[0][6] = result[0][7] = 0;
        if (description[0].length == 5) {
            result[0][5] = (description[0][4] & 0xff0000) >> 16;
            result[0][6] = (description[0][4] & 0xff00) >> 8;
            result[0][7] = description[0][4] & 0xff;
        }

        for (int i = 1; i < description.length; i++) {
            if (description[i][0] == _LEFT || description[i][0] == _NONE) {
                result[i][0] = Round(description[i][1] * multiple) + Left - result[0][0];
            } else if (description[i][0] == _CENTER) {
                result[i][0] = Round(Center - (devWidth / 2.0 - description[i][1] - 1) * multiple) - result[0][0];
            } else if (description[i][0] == _RIGHT) {
                result[i][0] = Round(Right - (devWidth - description[i][1] - 1) * multiple) - result[0][0];
            }
            result[i][1] = Round(description[i][2] * multiple) + Top - result[0][1];
            result[i][2] = (description[i][3] & 0xff0000) >> 16;
            result[i][3] = (description[i][3] & 0xff00) >> 8;
            result[i][4] = description[i][3] & 0xff;
            result[i][5] = result[i][6] = result[i][7] = result[i][8] = 0;
            if (description[i].length >= 5) {
                if (description[i].length == 6) {
                    result[i][8] = description[i][5];
                } else if (description[i][4] == 1) {
                    result[i][8] = description[i][4];
                } else {
                    result[i][5] = (description[i][4] & 0xff0000) >> 16;
                    result[i][6] = (description[i][4] & 0xff00) >> 8;
                    result[i][7] = description[i][4] & 0xff;
                }
            }
        }
        return result;
    }

    public int[][] GetFindColorArray(String description) {
        try {
            String[] desc = description.split(",");
            int devWidth = Integer.parseInt(desc[0].trim());
            int devHeight = Integer.parseInt(desc[1].trim());
            double multiple = (Bottom - Top + 1.0) / devHeight;

            int[][] result = new int[desc.length - 2][9];

            {
                String[] currentDesc = desc[2].trim().split("\\|");
                switch (currentDesc[0]) {
                    case "left":
                    case "none":
                        result[0][0] = Round(Integer.parseInt(currentDesc[1]) * multiple) + this.Left;
                        break;
                    case "center":
                        result[0][0] = Round(this.Center - (devWidth / 2.0 - Integer.parseInt(currentDesc[1]) - 1) * multiple);
                        break;
                    case "right":
                        result[0][0] = Round(this.Right - (devWidth - Integer.parseInt(currentDesc[1]) - 1) * multiple);
                        break;
                }
                result[0][1] = Round(Integer.parseInt(currentDesc[2]) * multiple) + this.Top;
                int color = Integer.parseInt(currentDesc[3].replace("0x", ""), 16);
                result[0][2] = (color & 0xff0000) >> 16;
                result[0][3] = (color & 0xff00) >> 8;
                result[0][4] = color & 0xff;
                result[0][5] = result[0][6] = result[0][7] = result[0][8] = 0;
                if (currentDesc.length >= 5) {
                    int offsetColor = Integer.parseInt(currentDesc[4].replace("0x", ""), 16);
                    result[0][5] = (offsetColor & 0xff0000) >> 16;
                    result[0][6] = (offsetColor & 0xff00) >> 8;
                    result[0][7] = offsetColor & 0xff;
                }
            }

            for (int i = 3, j = 1; i < desc.length; i++, j++) {
                String[] currentDesc = desc[i].trim().split("\\|");
                switch (currentDesc[0]) {
                    case "left":
                    case "none":
                        result[j][0] = Round(Integer.parseInt(currentDesc[1]) * multiple) + this.Left - result[0][0];
                        break;
                    case "center":
                        result[j][0] = Round(this.Center - (devWidth / 2.0 - Integer.parseInt(currentDesc[1]) - 1) * multiple) - result[0][0];
                        break;
                    case "right":
                        result[j][0] = Round(this.Right - (devWidth - Integer.parseInt(currentDesc[1]) - 1) * multiple) - result[0][0];
                        break;
                }
                result[j][1] = Round(Integer.parseInt(currentDesc[2]) * multiple) + this.Top - result[0][1];
                int color = Integer.parseInt(currentDesc[3].replace("0x", ""), 16);
                result[j][2] = (color & 0xff0000) >> 16;
                result[j][3] = (color & 0xff00) >> 8;
                result[j][4] = color & 0xff;
                result[j][5] = result[j][6] = result[j][7] = result[j][8] = 0;
                if (currentDesc.length >= 5) {
                    if (currentDesc[4].startsWith("0x")) {
                        int offsetColor = Integer.parseInt(currentDesc[4].replace("0x", ""), 16);
                        result[j][5] = (offsetColor & 0xff0000) >> 16;
                        result[j][6] = (offsetColor & 0xff00) >> 8;
                        result[j][7] = offsetColor & 0xff;
                    } else {
                        result[j][8] = Integer.parseInt(currentDesc[4]);
                    }

                    if (currentDesc.length == 6) {
                        result[j][8] = Integer.parseInt(currentDesc[5]);
                    }
                }
            }
            return result;
        }
        catch (Exception ex){
           this.AjFunc.ConsoleLog(ex.toString());
           return null;
        }
    }


    public boolean CompareColor(int[] description, int sim, int offset) {
        return BaseGraphicHelper.CompareColor(description, sim, offset);
    }

    public boolean CompareColorEx(int[][] description, int sim, int offset) {
        return BaseGraphicHelper.CompareColorEx(description, sim, offset);
    }

    public boolean CompareColorExLoop(int[][] description, int sim, int offset, long timeout, long timelag, int sign) throws InterruptedException {
        return BaseGraphicHelper.CompareColorExLoop(description, sim, offset, timeout, timelag, sign);
    }

    public Point FindMultiColor(int startX, int startY, int endX, int endY, int[][] description, int sim, int offset) {
        return BaseGraphicHelper.FindMultiColor(startX, startY, endX, endY, description, sim, offset);
    }

    public Point FindMultiColor(int[] range, int[][] description, int sim, int offset) {
        return BaseGraphicHelper.FindMultiColor(range[0], range[1], range[2], range[3], description, sim, offset);
    }

    public Point FindMultiColorLoop(int startX, int startY, int endX, int endY, int[][] description, int sim, int offset, long timeout, long timelag, int sign) throws InterruptedException {
        return BaseGraphicHelper.FindMultiColorLoop(startX, startY, endX, endY, description, sim, offset, timeout, timelag, sign);
    }

    public Point FindMultiColorLoop(int[] range, int[][] description, int sim, int offset, long timeout, long timelag, int sign) throws InterruptedException {
        return BaseGraphicHelper.FindMultiColorLoop(range[0], range[1], range[2], range[3], description, sim, offset, timeout, timelag, sign);
    }

    public List<Point> FindMultiColorEx(int startX, int startY, int endX, int endY, int[][] description, int sim, int filterNum) {
        return BaseGraphicHelper.FindMultiColorEx(startX, startY, endX, endY, description, sim, filterNum);
    }

    public List<Point> FindMultiColorEx(int startX, int startY, int endX, int endY, int[][] description, int sim) {
        return BaseGraphicHelper.FindMultiColorEx(startX, startY, endX, endY, description, sim);
    }

    public List<Point> FindMultiColorEx(int[] range, int[][] description, int sim, int filterNum) {
        return BaseGraphicHelper.FindMultiColorEx(range, description, sim, filterNum);
    }

    public List<Point> FindMultiColorEx(int[] range, int[][] description, int sim) {
        return BaseGraphicHelper.FindMultiColorEx(range, description, sim);
    }
// </editor-fold>
}
